package com.pqtest.api.config;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.*;

import javax.annotation.Resource;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.time.Duration;
import java.util.HashSet;
import java.util.Set;

import static java.util.Collections.singletonMap;

@Configuration
public class Redis {
    @Resource
    private LettuceConnectionFactory lettuceConnectionFactory;
    @Bean
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object target, Method method, Object... params) {
                StringBuffer sb = new StringBuffer();
                sb.append(target.getClass().getName());
                sb.append(method.getName());
                for (Object obj : params) {
                    sb.append(obj.toString());
                }
                return sb.toString();
            }
        };
    }
    @Bean
    CacheManager cacheManager(RedisConnectionFactory connectionFactory) {

        /* 默认配置， 默认超时时间为30s */
        RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration
                .ofSeconds(30L)).serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(valueSerializer())).disableCachingNullValues();

        /* 配置test的超时时间为120s*/
        RedisCacheManager cacheManager = RedisCacheManager.builder(RedisCacheWriter.lockingRedisCacheWriter
                (connectionFactory)).cacheDefaults(defaultCacheConfig)
                .withInitialCacheConfigurations(singletonMap("user", RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(60L)).serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(valueSerializer()))
                                .disableCachingNullValues()))

                .withInitialCacheConfigurations(singletonMap("testitem", RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(120L)).serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(valueSerializer()))
                        .disableCachingNullValues()))

                .withInitialCacheConfigurations(singletonMap("collect", RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(60L)).serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(valueSerializer()))
                        .disableCachingNullValues()))
                .transactionAware().build();

        return cacheManager;
    }

    @Bean
    @Primary
    public RedisTemplate<String, Serializable> redisCacheTemplate(LettuceConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Serializable> template = new RedisTemplate<>();
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        template.setConnectionFactory(redisConnectionFactory);

        return template;
    }

    private RedisSerializer<Object> valueSerializer() {
        return new GenericJackson2JsonRedisSerializer();
    }
}
